<template>
  <div id="com-action-bar" class="com-action-bar">
    <t-space>
      <template v-for="(item, key) in data">
        <!-- button -->
        <template v-if="!item.component || item.component === 'button'">
          <t-button
            :key="key"
            v-auth="item.auth || []"
            size="medium"
            :disabled="item.disabled"
            :theme="item.theme"
            :variant="item.variant"
            @click="onClick(item)"
            >{{ t(item.text) }}</t-button
          >
        </template>
        <!-- line -->
        <template v-if="item.component === 'line'">
          <t-divider :key="key" layout="vertical" />
        </template>
        <!-- tree -->
        <template v-if="item.component === 'dropdown'">
          <t-popup
            :key="key"
            v-model="visible"
            placement="bottom"
            show-arrow
            destroy-on-close
            :disabled="item.disabled"
          >
            <t-button size="medium" theme="default" variant="outline" :disabled="item.disabled">
              {{ t(item.text) }} <template #suffix> <t-icon name="chevron-down" size="16" /></template>
            </t-button>
            <template #content>
              <t-tree
                :data="item.options"
                :keys="{ label: 'catname', value: 'id' }"
                @click="onTreeItem(item, $event)"
              ></t-tree>
            </template>
          </t-popup>
        </template>
        <!-- radio button -->
        <template v-if="item.component === 'radio-button'">
          <t-radio-group :key="key" variant="primary-filled" :default-value="item.defaultValue" @change="onRadioChange">
            <t-radio-button v-for="(sv, sk) in item.options" :key="sk" :value="sv.value">
              <div style="display: flex; align-items: center; gap: 4px">
                <t-icon v-if="sv.icon" :name="sv.icon"></t-icon>
                <span>{{ sv.label }}</span>
              </div>
            </t-radio-button>
          </t-radio-group>
        </template>
        <!-- upload -->
        <template v-if="item.component === 'upload'">
          <t-upload
            :key="key"
            multiple
            accept="image/*"
            :headers="uploadHeader"
            :action="uploadUrl"
            :size-limit="sizeLimit"
            @success="onUploadSuccess"
          ></t-upload>
        </template>
      </template>

      <slot></slot>
    </t-space>
  </div>
</template>

<script setup lang="ts">
import { RadioValue, SizeLimitObj } from 'tdesign-vue-next';
import { PropType, ref } from 'vue';

import $api from '@/api';
import { SearchBarComponent, ThemeType } from '@/constants';
import { t } from '@/locales';
import { useUserStore } from '@/store';

export interface ActionBarItem {
  // 组件
  component?: SearchBarComponent;
  // 标记，用来处理事件判断逻辑
  key?: string;
  // 文本
  text?: string;
  // 权限
  auth?: string[];
  // 是否禁用
  disabled?: boolean;
  // 选型数据 dropdown/radio-button 组件使用
  options?: Recordable[];
  // 样式
  theme?: ThemeType;
  // 按钮形势 仅对按钮有效
  variant?: 'base' | 'outline' | 'dashed' | 'text';
  // 弹窗提示信息
  message?: string;
  // 默认值
  defaultValue?: number | string;
}

defineProps({
  data: {
    type: Array as PropType<ActionBarItem[]>,
    default: () => [],
  },
});

const emits = defineEmits(['action']);

const userStore = useUserStore();

const uploadUrl = import.meta.env.VITE_API_URL + $api.common.uploadUrl;
const uploadHeader = {
  Authorization: `Bearer ${userStore.token}`,
};
// 图片大小限制 2M
const sizeLimit: SizeLimitObj = {
  size: import.meta.env.VITE_API_URL_IMG_SIZE,
  unit: 'MB',
  message: `${t('common.imgSize')} {sizeLimit} MB`,
};

const onUploadSuccess = () => {
  emits('action', 'uploaded', null);
};

const visible = ref(false);

const onClick = (item: ActionBarItem) => {
  emits('action', 'click', item);
};
const onRadioChange = (val: RadioValue) => {
  emits('action', 'radio-change', val);
};

const onTreeItem = (item: ActionBarItem, e: any) => {
  emits('action', 'click', { ...item, node: e.node.data });
  visible.value = false;
};
</script>

<style lang="less" scoped>
.t-upload :deep(.t-upload__single-display-text) {
  display: none;
}
</style>
